:
eval 'exec perl -S $0 ${1+"$@"}'
if 0;

use Getopt::Long;
use Carp;
use Cwd qw (cwd);
use Cwd 'chdir';

use strict;


### global variables ###

my $mencoder = 'mencoder -msglevel all=0';
#my $mplayer = 'mplayer -msglevel all=-1:vfilter=4 -nosound';
my $mplayer = 'mplayer -nosound';


my $is_dvd;

my $OUTPUT_FILM_NAME='recoded.avi';
#my $MOVIE_PARTS='VTS_05_1.VOB  VTS_05_2.VOB  VTS_05_3.VOB  VTS_05_4.VOB  VTS_05_5.VOB';
my $MOVIE_PARTS;#='tri_brata_1995.mkv';


my $TEST_PART;# = 'tri_brata_1995.mkv';
#my $TEST_PART='VTS_05_3.VOB';



#TEST_PART=Juha.avi
print "$OUTPUT_FILM_NAME $MOVIE_PARTS\n";


#language ID
#AUDIO_TRACK_ID=-aid\ 0x81
my $AUDIO_TRACK_ID = '';#'-aid 1';
#Resoluton of Motorola Defy is 854 x 480
my $SCALE;# = 'scale=932:576';
# Here: первые два параметра - "Реальная ширина":"Реальная высота" (до скалирования)
#this parameter is defined with mplayer -vf cropdetect -ss 180 #(posle 3 minut filma)
#my $CROP = 'crop=656:576:34:0';
my $CROP;
#my $START_POS="-ss 1:17:18"
# Длина итогового ролика
#my $END_POS="-endpos 00:00:21"
#my $BITRATE=1238
my $BITRATE=2000;
my $PP=6;

####### REVISE!!! :Deinterlacing: uncomment when there is an interlaced video
# deinterlacer 'pp=fd' fuer Comics am besten geeignet.
# other good deinterlacer: pp=0x20000
# other good deinterlacer: pp=ci
# all other deinterlacer are stupid!
#my $DEINTERLACE_OPTION = 'pp=fd';
my $DEINTERLACE_OPTION;

#PICTURE_ASPECT="-aspect 16:9"
#PICTURE_ASPECT="-aspect 1.33:1"
#my $PICTURE_OPTIONS="$PICTURE_ASPECT -vf $DEINTERLACE_OPTION$CROP$SCALE"
my $PICTURE_OPTIONS = '';

no strict;

#print $PICTURE_OPTIONS;

#my $FORCE_IDX="-forceidx"
my $VIDEO_CODEC_OPTS="$FORCE_IDX -ovc lavc -ffourcc DX50 -sws 2 -lavcopts vcodec=mpeg4:vhq:trell=yes:v4mv=yes:vglobal=1:aglobal=1:vbitrate=$BITRATE:vrc_eq=tex:mbd=2:cmp=2:subcmp=2:threads=4";
my $TIME_OPTIONS="$START_POS $END_POS";
my $TEST_TIME_OPTIONS="-ss 240";

use strict;

my $AUDIO_CODEC_OPTS = '-af pan=2:1:0:0:0.5:0.5:0:0:1:1:1:1:1 -oac mp3lame -lameopts vbr=2:q=3:aq=0';
my $AUDIO_TRACK_OPTS="$AUDIO_CODEC_OPTS $AUDIO_TRACK_ID";
#my $AUDIO_TRACK_OPTS="-oac mp3lame -lameopts cbr:br=128 $AUDIO_TRACK_ID"
#my $AUDIO_TRACK_OPTS="-oac lavc -lavcopts acodec=aac:abitrate=$AUDIO_BITRATE"
#my $AUDIO_TRACK_OPTS="-oac copy"
#my $AUDIO_TRACK_OPTS="-nosound"

my $test = 0;
my $full_convert = 0;
my $autodetect_scale = 1;
my $second_sound_track;
my $LOCATION;
my $SUBTITLES;
### main ###
 
GetOptions ('test!' => \$test, 'help!' => \&print_help, 'convert!' => \$full_convert, 'dont_detect_scale' =>  sub { $autodetect_scale = 0 }, 'add_sound_track=s' => \$second_sound_track, 'movie_file=s' => \$MOVIE_PARTS, 'movie_test_part=s' => \$TEST_PART, 'dvd!' => \$is_dvd, 'path=s' => \$LOCATION, 'extract_subtitles=s' => \$SUBTITLES);

if (!$LOCATION) {
    if ($is_dvd) {
        croak("MUST define path for DVD!!");
    } else {
        $LOCATION = '/disk2/Movies'; 
    }   
}

if ($SUBTITLES) {
    $SUBTITLES = '-sid ' . $SUBTITLES;
} else {
	$SUBTITLES = '-nosub';
}



if ($test && $full_convert) {
    croak('Colliding options!!');
}

if (!$test && !$full_convert) {
    $full_convert++;
}
if (!$TEST_PART && !$MOVIE_PARTS) {
    croak("No video files specified!!");
}

if ($is_dvd) {
    $MOVIE_PARTS = "-dvd-device $LOCATION $MOVIE_PARTS";
}

$TEST_PART = $MOVIE_PARTS if (!$TEST_PART && $MOVIE_PARTS);

chdir $LOCATION;
cwd();

if ($autodetect_scale) {
    $CROP = '';
    detect_crop();
    detect_scale();
};

foreach my $option ($DEINTERLACE_OPTION, $CROP, $SCALE) {
    add_option(\$PICTURE_OPTIONS, $option);
};

if ($PICTURE_OPTIONS) {
    $PICTURE_OPTIONS = '-vf ' . $PICTURE_OPTIONS;
}

if ($test) {
    run_test_convert();
}

if ($full_convert) {
    convert();
}


#########################
#                       #
#      Procedures       #
#                       #
#########################

sub convert {
    my $build_time = time;
    unlink $OUTPUT_FILM_NAME, 'movie.avi', 'frameno.avi', 'lavc_stats.txt';

    if ($SUBTITLES) {
        print "\n\nExtracting subtitles\n\n";
        system("$mencoder $TIME_OPTIONS -nosound -ovc nuv $SUBTITLES -o /dev/null -vobsubout subtitles $MOVIE_PARTS");
        #system("$mencoder $TIME_OPTIONS -nosound -ovc nuv $SUBTITLES -o /dev/null -vobsubout subtitles $MOVIE_PARTS");
	}

    print "\n\nRun first pass of convertion\n\n";

    system("$mencoder $TIME_OPTIONS -nosub -nosound -o /dev/null $VIDEO_CODEC_OPTS:vpass=1:turbo $PICTURE_OPTIONS $MOVIE_PARTS");


    print "\n\nRun second pass of convertion\n\n";


    system("$mencoder $TIME_OPTIONS -nosub $AUDIO_TRACK_OPTS $VIDEO_CODEC_OPTS:vpass=2       $PICTURE_OPTIONS -o $OUTPUT_FILM_NAME $MOVIE_PARTS");
    if ($second_sound_track) {
        print "\n\nExtracting sound track ID $second_sound_track\n\n";
        system("$mencoder -ovc frameno $TIME_OPTIONS $AUDIO_CODEC_OPTS -aid $second_sound_track $MOVIE_PARTS -o $second_sound_track" . '_audio_track.avi');
    };

    use strict;

    my $build_duration = get_time_line(time - $build_time);
    print "\nMovie convertion has taken: $build_duration\n\n";
    exit(0);
}

sub run_test_convert {
    unlink $OUTPUT_FILM_NAME, 'movie.avi', 'frameno.avi', 'lavc_stats.txt';
    no strict;
    system("$mencoder $TEST_TIME_OPTIONS $SUBTITLES  $VIDEO_CODEC_OPTS $PICTURE_OPTIONS $AUDIO_TRACK_OPTS -o $OUTPUT_FILM_NAME $TEST_PART");
    use strict;
}

sub detect_crop {
    my $width = 0;
    my $height = 0;
    my $x_offset = 0;
    my $y_offset = 0;
    if (open(MPLAYEROUTPUT, "$mplayer -endpos 00:00:03 $TEST_TIME_OPTIONS -vo null -vf cropdetect $TEST_PART |")) {
        my @scale_strings = <MPLAYEROUTPUT>;
        close MPLAYEROUTPUT;

        foreach (@scale_strings) {
            chomp;
            next if (!/\[CROP\]/);
            if (/crop=(\d+):(\d+):(\d+):(\d+)/) {
                $width = $1 if (($1 < $width) || ($width == 0));
                $height = $2 if (($2 < $height) || ($height == 0));
                $x_offset = $3 if ($x_offset < $3);
                $y_offset = $4 if ($y_offset < $4);

            }    
        };
    }
    $CROP = "crop=$width:$height:$x_offset:$y_offset";
}

sub detect_scale {
    if (open(MPLAYEROUTPUT, "$mplayer -endpos 00:00:03 -vf $CROP -vo null -lavdopts debug=1 $TEST_PART |")) {
        my @scale_strings = <MPLAYEROUTPUT>;
        close MPLAYEROUTPUT;

        foreach (@scale_strings) {
            chomp;
            next if (!/^VO/);
            my @string_parts = split(/\s+/,  $_);
            print "@string_parts\n";            
            $string_parts[4] =~ s/x/:/;
            $SCALE = 'scale=' . $string_parts[4];
        };
    }
}


sub print_help {
    print STDERR "\n$0\n\n";
    print STDERR "Syntax:    $0    --test|--convert [--dont_detect_scale] [--add_sound_track=track_id] [--movie_file=file_name] [--dvd] [--path=directory_path] [--extract_subtitles=sid] --help\n";
    print STDERR "        --convert         - convert video to avi with default values (first soundtrack as stereo mp3, 2000 mbps video, no subtitles)\n";
    print STDERR "        --add_sound_track - extract second sound track with id as shown in mplayer output\n";
    # TODO: example for DVD 
    print STDERR "        --movie_file      - specify which file should be converted. In case of DVD - which DVD stream. Example: dvd://1\n";
    print STDERR "                          - the same parameter, that mplayer uses for playing videos/DVD\n";
    print STDERR "        --path            - path to directory where video file is located. In case of DVD - where located VIDEO_TS folder\n";
    exit(0);
}

sub add_option {
    my ($parameter, $option) = @_;
    if (defined $option) {
        if ($$parameter) {
            $$parameter .= ',';
        }
        $$parameter .= $option;
    }
}

sub get_time_line {
    use integer;
    my $seconds = shift;
    my $hours = $seconds/3600;
    my $minits = ($seconds/60)%60;
    $seconds -= ($hours*3600 + $minits*60);
    return(sprintf("%02d\:%02d\:%02d" , $hours, $minits, $seconds));
};
